<template>
  <div class="app-container">
    <el-form
      v-show="showSearch"
      ref="queryForm"
      :inline="true"
      :model="formInline"
      size="small"
      class="demo-form-inline"
    >

      <el-form-item label="角色名称">
        <el-input v-model="formInline.roleName" placeholder="请输入角色名称" clearable />
      </el-form-item>

      <el-form-item label="权限字符">
        <el-input v-model="formInline.roleKey" placeholder="请输入权限字符" clearable />
      </el-form-item>

      <el-form-item label="状态">
        <el-select v-model="formInline.status" placeholder="角色状态">
          <el-option label="正常" value="0" />
          <el-option label="停用" value="1" />
        </el-select>
      </el-form-item>

      <el-form-item label="创建时间" required>
        <span class="demonstration" />
        <el-date-picker
          v-model="value1"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        />
      </el-form-item>
      <br>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="onSubmit">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="reset">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
      </el-col>
      <!--      <el-col :span="1.5">-->
      <!--        <el-button type="success" plain icon="el-icon-edit" size="mini" @click="handleUpdate">修改</el-button>-->
      <!--      </el-col>-->
      <el-col :span="1.5">
        <el-button

          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
        >导出当前页</el-button>
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExportAll"
        >导出全部</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDeleteBatch"
        >删除
        </el-button>
      </el-col>
      <!--      <el-col :span="1.5">-->
      <!--        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>-->
      <!--      </el-col>-->
      <!--隐藏搜索+刷新-->
      <right-toolbar
        :show-search.sync="showSearch"
        @queryTable="onSubmit"
      />
    </el-row>

    <!-- 新增对话框 开始   -->
    <el-dialog title="添加角色" :visible.sync="dialogFormVisible">
      <el-form ref="form" :model="form" :rules="rules">

        <el-form-item label="角色名称" :label-width="formLabelWidth" prop="roleName">
          <el-input v-model="form.roleName" maxlength="15" show-word-limit placeholder="请输入角色名称" />
        </el-form-item>

        <el-form-item label="权限字符" :label-width="formLabelWidth" prop="roleKey">
          <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
        </el-form-item>

        <el-form-item label="角色顺序" :label-width="formLabelWidth">
          <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
        </el-form-item>

        <el-form-item label="状态">
          <el-radio-group v-model="form.status">
            <el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">
              {{ dict.dictLabel }}
            </el-radio>
          </el-radio-group>
        </el-form-item>

        <!--                        // 多选的按钮-->
        <el-form-item label="菜单权限">
          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动
          </el-checkbox>
          <el-tree
            ref="menu"
            class="tree-border"
            :data="menuOptions"
            show-checkbox
            node-key="menuId"
            :check-strictly="!form.menuCheckStrictly"
            empty-text="加载中，请稍后"
            :props="defaultProps"
          />
        </el-form-item>
        <el-form-item label="备注" :label-width="formLabelWidth">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveForm()">确 定</el-button>
      </div>
    </el-dialog>
    <!--对话框 end-->

    <!--表格数据 开始-->
    <el-table v-loading="loading" :data="roleList" stripe border @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" :selectable="selectHandle" />
      <el-table-column label="角色编号" prop="roleId" width="120" />
      <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
      <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
      <el-table-column label="显示顺序" prop="roleSort" width="80" align="center" />

      <el-table-column label="状态" width="70" align="center">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.status"
            active-value="0"
            inactive-value="1"
            @change="handleStatusChange(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column label="创建时间" align="center" prop="createTime">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="修改时间" align="center" prop="updateTime">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.updateTime) }}</span>
        </template>
      </el-table-column>

      <el-table-column label="操作" align="center" class-name="small-padding " width="200px">
        <template v-if="scope.row.roleId !== 1" slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteOne(scope.row)">删除</el-button>

          <el-dropdown trigger="click" size="mini">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-d-arrow-right el-icon--right"
              @click.native="more"
            >更多
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item icon="el-icon-plus" @click.native="dataPermission(scope.row)">数据权限</el-dropdown-item>
              <el-dropdown-item icon="el-icon-circle-plus" @click.native="AssignUsers(scope.row)">分配用户</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>

        </template>
      </el-table-column>
    </el-table>
    <!--表格   结束-->

    <!-- 分配数据权限 开始   -->
    <el-dialog title="分配数据权限" :visible.sync="dataPermissionDialogForm">
      <el-form :model="formData">

        <el-form-item label="角色名称" :label-width="formLabelWidth" prop="roleName">
          <el-input v-model="formData.roleName" disabled maxlength="15" show-word-limit placeholder="请输入角色名称" />
        </el-form-item>

        <el-form-item label="权限字符" :label-width="formLabelWidth" prop="roleKey">
          <el-input v-model="formData.roleKey" disabled placeholder="请输入权限字符" />
        </el-form-item>

        <el-form-item label="权限范围" :label-width="formLabelWidth">
          <!--          <template>-->
          <!--            <el-select v-model="value" placeholder="请选择" @change="powChange">-->
          <!--              <el-option-->
          <!--                v-for="item in options"-->
          <!--                :key="item.value"-->
          <!--                :label="item.label"-->
          <!--                :value="item.value">-->
          <!--              </el-option>-->
          <!--            </el-select>-->
          <!--          </template>-->

          <el-tree
            ref="dept"
            class="tree-border"
            :data="powOptions"
            show-checkbox
            node-key="deptId"
            empty-text="加载中，请稍后"
            :check-strictly="checkStrictly"
            :default-expand-all="true"
            :props="powOptionsProps"
          />
        </el-form-item>

        <!--        <el-form-item label="数据权限">-->
        <!--          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>-->
        <!--          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>-->
        <!--          <el-checkbox v-model="formData.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>-->

        <!--        </el-form-item>-->

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dataPermissionDialogForm = false">取 消</el-button>
        <el-button type="primary" @click="savePowForm()">确 定</el-button>
      </div>
    </el-dialog>

    <!--分页 开始-->
    <el-pagination
      :current-page="current"
      :page-sizes="[2,5, 10, 20, 40]"
      :page-size="size"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
    <!--分页 结束-->
  </div>
</template>

<script>
import { parseTime } from '../../../utils'
import store from '../../../store'
import { getToken } from '../../../utils/auth'

var userName = store.getters.name
export default {
  name: 'Index',
  data() {
    return {
      title: '',
      // 表单校验
      rules: {
        roleName: [
          { required: true, message: '角色名称不能为空', trigger: 'blur' }
        ],
        roleKey: [
          { required: true, message: '权限字符不能为空', trigger: 'blur' }
        ],
        roleSort: [
          { required: true, message: '角色顺序不能为空', trigger: 'blur' }
        ]
      },
      // 菜单列表  绑定el-tree 的data
      menuOptions: [],

      menuExpand: false,
      menuNodeAll: false,

      props: { // ??????
        label: 'name',
        children: 'zones'
      },

      defaultProps: {
        children: 'menus', // 对应着后后台集合里的子集合 属性名称
        label: 'menuName'
      },
      textarea: '',
      menuCheckStrictly: true,

      dialogFormVisible: false, // 添加/修改框默认关闭
      form: {
        menuIds: []
      }, // 添加数据
      menuIds: [],
      formLabelWidth: '120px',

      statusOptions: [], // 角色状态

      single: true, // 非单个禁用
      multiple: true, // 非多个禁用
      ids: [], // 选中数组
      // -------------------

      deptIds: [],
      dataPermissionDialogForm: false,

      checkStrictly: false,
      // 分配权限对话框
      formData: {
        deptIds: []
      },

      options: [{
        value: '选项1',
        label: '自定义数据类型'
      }, {
        value: '选项2',
        label: '全部数据类型'
      }],

      value: '',
      powChang: false,

      // 权限菜单列表  绑定el-tree 的data
      powOptions: [],

      powOptionsProps: {
        children: 'depts', // 对应着后后台集合里的子集合 属性名称
        label: 'deptName'
      },

      // ----------------------------------------------------
      showSearch: true,
      loading: false, // 遮罩层

      roleList: [], // 角色数据
      current: 1, // 当前页数
      size: 2, // 当前条数
      total: 0, // 总条数
      value1: '', // 时间
      role: {}, // 模糊查询表单数据
      formInline: { // 条件查询
        roleName: '',
        roleKey: '',
        status: '',
        startTime: '',
        endTime: ''
      }
    }
  },
  created() {
    this.loadRolesList(this.current)
  },

  methods: {
    // 新增按钮
    handleAdd() {
      this.reset2()
      this.title = '添加角色'
      this.dialogFormVisible = true
      this.$nextTick(function() { // Cannot read property 'setCheckedKeys' of undefined",,因为this.dialogVisible = true时并没有立即更新dom，而是等整个逻辑执行完后再一次新渲染，因此此时的弹框并未渲染，在dom树中是不存在的，
        // this.$refs.tree is undefined的所以setCheckedKeys肯定也是undefined。
        this.$refs.menu.setCheckedKeys([])
      })
    },
    // 表单重置
    reset2() {
      if (this.$refs.menu != undefined) {
        this.$refs.menu.setCheckedKeys([])
      }
      this.menuExpand = false
      this.menuNodeAll = false
      this.deptExpand = true
      this.deptNodeAll = false
      this.form = {
        roleId: '',
        roleName: '',
        roleKey: '',
        roleSort: 1,
        status: '0',
        menuIds: [],
        deptIds: [],
        menuCheckStrictly: 1,
        remark: ''
        // createBy: userName
      }
    },

    // 加载页面数据
    loadRolesList(current) {
      this.loading = true
      /* 获取当前用户名*/
      // console.log(userName)
      // 分页数据
      this.axios.get('/sysRole/roleList',
        {
          params: {
            current: current,
            size: this.size,
            roleName: this.formInline.roleName,
            roleKey: this.formInline.roleKey,
            status: this.formInline.status,
            startTime: this.formInline.startTime,
            endTime: this.formInline.endTime
            // ------------------------------
            // userName: userName
          }
        }).then(result => {
        // 处理后台数据(将后台result.data数据与roleList集合绑定)
        this.roleList = result.data.data.records
        this.total = result.data.data.total
      })
      // //查询 角色状态
      this.axios.get('/sysRole/status').then(res => {
        this.statusOptions = res.data.data
      })

      // 新增 菜单树 数据
      this.axios.get('/sysMenu/menu/', {
        params: {
          menuName: '',
          status: ''
        }
      }).then(res => {
        this.menuOptions = res.data.data
      })

      // 数据 权限 树 结构展示
      this.axios({
        url: '/sysDept/dept/',
        params: {
          deptName: '',
          status: ''
        }
      }).then(res => {
        this.powOptions = res.data.data
      })

      this.loading = false
    },

    // 添加/修改 提交按钮
    async saveForm() {
      if (this.title === '添加角色') {
        this.form.createBy = userName // 创建者
        this.form.menuIds = this.$refs.menu.getCheckedKeys() // 将数据添加到的对话表单框 from 对象中  返回目前被选中的节点的 key 所组成的数组
        this.menuOptions = this.getMenuAllCheckedKeys() // 调用  获取所有菜单节点数据方法

        console.log(this.form)
        //  添加
        await this.axios({
          url: '/sysRole/add',
          method: 'post',
          data: this.form
        }).then(res => {
          if (res.data.data === 'ok') {
            this.$message.success('添加成功')
          } else {
            this.$message.error('添加失败')
          }
        })
      } else if (this.title === '修改角色') {
        console.log('修改角色')
        this.form.menuIds = this.$refs.menu.getCheckedKeys()
        this.menuOptions = this.getMenuAllCheckedKeys()

        //  修改
        await this.axios({
          url: '/sysRole/update',
          method: 'post',
          data: this.form
        }).then(res => {
          if (res.data.data === 'ok') {
            this.$message.success('修改成功')
          } else {
            this.$message.error('修改失败')
          }
        })
      }
      this.loadRolesList(this.current)
      this.dialogFormVisible = false
    },

    // 点击弹出修改框
    async handleUpdate(row) {
      if (row.status !== '0') {
        this.$message.error('当前角色已被停用！无法进行修改操作！')
      } else {
        this.title = '修改角色'
        this.dialogFormVisible = true
        this.form = row
        console.log(this.form)
        await this.axios.get('/sysRoleMenu/getMenuIdsByRoldId', {
          params: {
            roleId: this.form.roleId
          }
        }).then(res => {
          this.menuIds = [] //   置空

          for (let i = 0; i < res.data.data.length; i++) { // 遍历添加
            this.menuIds.push(res.data.data[i].menuId)
          }
          this.$nextTick(() => {
            this.$refs.menu.setCheckedKeys(this.menuIds)
          })
        })
      }
    },

    // 树权限（展开/折叠）
    handleCheckedTreeExpand(value, type) {
      if (type == 'menu') {
        const treeList = this.menuOptions
        for (let i = 0; i < treeList.length; i++) {
          this.$refs.menu.store.nodesMap[treeList[i].menuId].expanded = value
        }
      } else if (type == 'dept') {
        // let treeList = this.deptOptions;
        // for (let i = 0; i < treeList.length; i++) {
        //   this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
        // }
      }
    },
    // 树权限（全选/全不选）
    handleCheckedTreeNodeAll(value, type) {
      if (type == 'menu') {
        this.$refs.menu.setCheckedNodes(value ? this.menuOptions : [])
      } else if (type == 'dept') {
        // this.$refs.dept.setCheckedNodes(value ? this.deptOptions : []);
      }
    },
    // 树权限（父子联动）
    handleCheckedTreeConnect(value, type) {
      if (type == 'menu') {
        this.form.menuCheckStrictly = !!value
      } else if (type == 'dept') {
        // this.form.deptCheckStrictly = value ? true : false;
      }
    },
    // 所有菜单节点数据
    getMenuAllCheckedKeys() {
      // 目前被选中的菜单节点
      const checkedKeys = this.$refs.menu.getCheckedKeys() // 返回目前被选中的节点的 key 所组成的数组
      console.log('目前被选中的菜单节点 所有')
      console.log(checkedKeys)

      // 被选中的菜单节点
      const halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys() // 返回半选中的节点的 key 所组成的数组
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys) // unshift() 方法将一个或多个元素添加到数组的开头，并返回新数组的长度
      console.log('被半选中的菜单节点')
      console.log(halfCheckedKeys)

      console.log('合并后')
      console.log(checkedKeys)

      return checkedKeys // 返回  合并后 []  为什么合并？？？？？？？ 因为只选 子节点 只会返回子节点的id ,所有还需要父节点的id
    },

    // 单删除
    async handleDeleteOne(row) {
      this.$confirm('是否删除角色编号为"' + row.roleId + '"的数据项？', '警告', {
        confirmButtonClass: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        await this.axios({
          url: 'sysRole/delete',
          method: 'delete',
          params: {
            roleId: row.roleId
          }
        }).then(res => {
          if (res.data.data == 'ok') {
            this.$message.success('删除成功')
          } else {
            this.$message.error('删除失败')
          }

          const totalPage = Math.ceil((this.total - 1) / this.size) // 总页数
          this.current = this.current > totalPage ? totalPage : this.current
          this.current = this.current < 1 ? 1 : this.current

          this.loadRolesList(this.current)
        })
      }
      )
    },
    // 批量删除
    async handleDeleteBatch() {
      await this.axios({
        url: 'sysRole/BatchDelete',
        method: 'delete',
        data: this.ids
      }).then(res => {
        if (res.data.data == 'ok') {
          this.$message.success('删除成功')
        } else {
          this.$message.error('删除失败')
        }
      })
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.roleId)
      this.single = selection.length != 1
      this.multiple = !selection.length
    },

    // 角色状态修改
    async handleStatusChange(row) {
      // console.log(row)
      const text = row.status == '0' ? '启用' : '停用'
      this.$confirm('是否' + text + '角色编号为"' + row.roleId + '"的数据项？', '注意', {
        confirmButtonClass: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        await this.axios.put('sysRole/updateRoleStatus', row).then(res => {
          if (res.data.data === 'ok') {
            this.$message.success(text + '成功')
          }
        })
      })
    },

    // 多选中禁用一行
    selectHandle(row) {
      return !(row.roleKey === 'admin')
    },

    // -------------------------------------------------------------------------------------------------------
    // 点击更多
    more() {
      this.value = ''
      if (this.$refs.dept != undefined) {
        this.$refs.dept.setCheckedKeys([])
      }
      this.formData = {
        status: '0',
        deptIds: []
      }
    },
    // 切换权限
    // powChange(){
    //   this.powChang = this.value === '选项1';
    //     this.dataPermission(this.formData);
    // },

    // 数据权限
    dataPermission(row) {
      if (row.status !== '0') {
        this.$message.error('当前角色已被停用！无法进行修改操作！')
      } else {
        // 行数数据
        this.formData = row

        // 对话框
        this.dataPermissionDialogForm = true

        // 该角色 有的权限数据
        this.axios({
          url: '/sysDept/RoleId/',
          params: {
            roleId: this.formData.roleId
          }
        }).then(res => {
          this.deptIds = [] //   置空
          for (let i = 0; i < res.data.data.length; i++) { // 遍历添加
            this.deptIds.push(res.data.data[i].deptId)
          }
          this.checkStrictly = true

          this.$nextTick(() => {
            this.$refs.dept.setCheckedKeys(this.deptIds)
            this.checkStrictly = false
          })
        })
      }
    },

    // 保存权限  就是修改角色权限sys_role_dept
    savePowForm() {
      console.log('保存权限')

      const checkedKeys = this.$refs.dept.getCheckedKeys() // 所有 打勾 节点

      var halfCheckedNodes = this.$refs.dept.getHalfCheckedKeys()// 半选状态 就是 - 状态

      checkedKeys.unshift.apply(checkedKeys, halfCheckedNodes)

      this.formData.deptIds = checkedKeys

      this.axios({
        url: '/sysRole/pow',
        method: 'put',
        data: this.formData
      }).then(res => {
        if (res.data.data === 'ok') {
          this.$message.success('修改成功')
        } else {
          this.$message.error('修改失败')
        }
      })

      this.dataPermissionDialogForm = false
      this.loadRolesList(this.current)
    },

    // -----------------------------------------------

    // 模糊查询提交按钮
    onSubmit() {
      this.loading = true
      // 将日期转换为字符串
      if (this.value1[0] != null) {
        this.formInline.startTime = parseTime(this.value1[0]).slice(0, 10)
        this.formInline.endTime = parseTime(this.value1[1]).slice(0, 10)
      }

      this.loadRolesList(this.current)
      this.value1 = ''
    },
    // 重置按钮
    reset() {
      this.formInline = {
        roleName: '',
        roleKey: '',
        status: ''
      },
      this.value1 = ''
    },

    handleSizeChange(val) {
      console.log(`每页 ${val} 条`)
      this.size = val
      this.loadRolesList(this.current)
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`)
      this.current = val
      this.loadRolesList(this.current)
    },

    // 导出当前页数据
    handleExport() {
      window.open('http://localhost:8080/sysRole/export?current=' + this.current + '&size=' + this.size + '&roleName=' +
          this.formInline.roleName + '&roleKey=' + this.formInline.roleKey + '&status=' + this.formInline.status +
          '&startTime=' + this.formInline.startTime + '&endTime=' + this.formInline.endTime + '&userName=' + '' + '&Authorization=' + getToken())
    },
    // 导出所有数据
    handleExportAll() {
      console.log('导出所有数据')
      window.open('http://localhost:8080/sysRole/export?current=' + 1 + '&size=' + this.total + '&roleName=' +
          this.formInline.roleName + '&roleKey=' + this.formInline.roleKey + '&status=' + this.formInline.status +
          '&startTime=' + this.formInline.startTime + '&endTime=' + this.formInline.endTime + '&userName=' + '' + '&Authorization=' + getToken())
    },

    /* 格式化时间*/
    parseTime(time) {
      var date = new Date(time)
      return parseTime(date)
    }

  }

}

</script>

<style scoped>
  .tree-line {
    background: transparent;
    color: #81b0ff;
    font-size: 14px;
    line-height: 20px;
    margin-bottom: 15px;
  }
</style>
